package com.ltsznh.android.locationreporting;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.util.Log;

import com.ltsznh.android.locationreporting.db.dbo;
import com.ltsznh.android.locationreporting.util.Tools;

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class LrReceiver extends BroadcastReceiver {
    //
    private static Context context;

    private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private static final SimpleDateFormat simpleTimeFormat = new SimpleDateFormat("HH:mm:ss");

    // 测试使用的日志 Tag
    private static final String TAG = "dddd";

    private static AlarmManager alarmManager;//定时

    private static LocationManager locationManager;
    //位移距离内更新记录
    private static final int DISTANCE = 10;
    // 接受位置更新的监听器
    protected static LocationListener locationListener = new LrLocationListener();

    private static Intent intent1 = null;
    private static PendingIntent sender;
    private static long alarmTime = 3600000;

    private static long locationTime = 6000;
//    private static long locationDistance = 10;

    public static void init(Context ctx, Intent it) {
        if (ctx != null) {
            context = ctx;
        }
        refreshUpdates(100);
    }


    private static void initLr(Context context) {
        // 获取 LocationManager
        if (locationManager == null)
            locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        // 获取最后一个记录的地址信息,根据GPS，NETWORK,均保存
//        Location lastKnownLocation = locationManager
//                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
//        if (lastKnownLocation != null) report(lastKnownLocation);
//        else Log.v("dddd", "null GPS");
//        lastKnownLocation = locationManager
//                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//        if (lastKnownLocation != null) report(lastKnownLocation);
//        else Log.v("dddd", "null NETWORK_PROVIDER");
//        lastKnownLocation = locationManager
//                .getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
//        if (lastKnownLocation != null) report(lastKnownLocation);
//        else Log.v("dddd", "null PASSIVE_PROVIDER");

        // 注册监听器接受位置更新
//        locationManager.requestLocationUpdates(currentProvider, 0, 0,
//                locationListener);
//

        //获取设备列表，按类别找精度最高的；
//        locationManager.removeUpdates(locationListener);
//        List<String> provider = locationManager.getProviders(true);
//        if (provider.contains(LocationManager.GPS_PROVIDER)) {
//            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
//                    locationListener);
//            Log.v("dddd", " GPS_PROVIDER");
//        } else if (provider.contains(LocationManager.NETWORK_PROVIDER)) {
//            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
//                    locationListener);
////            init(context,intent,true);
//            Log.v("dddd", " NETWORK_PROVIDER");
//        } else if (provider.contains(LocationManager.PASSIVE_PROVIDER)) {
//            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
//                    locationListener);
//            Log.v("dddd", " PASSIVE_PROVIDER");
//        }
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_MEDIUM);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        String provider = locationManager.getBestProvider(criteria, true);
        Log.v("dddd", provider);

//        10分钟、10米距离监听
        locationManager.removeUpdates(locationListener);
        locationManager.requestLocationUpdates(provider, locationTime, DISTANCE, locationListener);

//一个小时守护一次监听
        if (intent1 == null) intent1 = new Intent(context, LrReceiver.class);
        if (sender == null)
            sender = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_CANCEL_CURRENT);
        if (alarmManager == null) {
            alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + alarmTime, sender);
        }
    }


    public static void removeUpdates() {
        if (locationManager != null) locationManager.removeUpdates(locationListener);
        if (alarmManager != null && sender != null) alarmManager.cancel(sender);
    }

    public static void refreshUpdates(long time) {
        if (sender == null) {
            intent1 = new Intent(context, LrReceiver.class);
            sender = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_CANCEL_CURRENT);
        }
        if (alarmManager == null) {
            alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        }
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + time, sender);
    }

    public synchronized static void report(Location location) {
        ContentValues values = getLocationValues(location);
        Log.v("dddd", "get Location:" + values);

        Cursor cursor = dbo.rawQueryCursor(context, "SELECT id," +
                "       provider," +
                "       latitude," +
                "       longitude," +
                "       accuracy," +
                "       altitude" +
                "  FROM lr_details" +
                " ORDER BY reportDatetime DESC" +
                " LIMIT 2;", null);
        if (cursor.getCount() > 0) {
            cursor.moveToFirst();
            Location location1 = getLocationByValues(cursor);
            String oldId = cursor.getString(cursor.getColumnIndex("id"));

            if (cursor.moveToNext()) {
                Location location2 = getLocationByValues(cursor);

                if (location1.distanceTo(location2) < DISTANCE) {
                    if (location1.distanceTo(location) < DISTANCE) {//位置重复，更新位置记录信息
                        values.remove("id");
                        dbo.updateData(context, "lr_details", values, "id = ?", new String[]{oldId});
                    } else {//位置变化
                        reportData(values);
                    }
                } else {//无两条相同数据
                    reportData(values);
                }
            } else {//无两条数据
                reportData(values);
            }
        } else {//无数据
            reportData(values);
        }
        cursor.close();
    }

    private static Location getLocationByValues(Cursor cursor) {
        Location location = new Location(cursor.getString(cursor.getColumnIndex("provider")));
        location.setLatitude(cursor.getDouble(cursor.getColumnIndex("latitude")));
        location.setLongitude(cursor.getDouble(cursor.getColumnIndex("longitude")));
        location.setAltitude(cursor.getDouble(cursor.getColumnIndex("altitude")));

        return location;
    }


    private static void reportData(ContentValues values) {
        dbo.insertData(context, "lr_details", null, values);
    }

    /**
     */
    public static ContentValues getLocationValues(Location location) {
        Calendar calendar = Calendar.getInstance();

        ContentValues values = new ContentValues();
        values.put("id", Tools.getId(calendar));
        values.put("entryDate", simpleDateFormat.format(calendar.getTime()));
        values.put("entryTime", simpleTimeFormat.format(calendar.getTime()));

        values.put("userCode", "");
        values.put("userName", "");
        values.put("provider", location.getProvider());
        calendar.setTimeInMillis(location.getTime());
        values.put("reportDateTime", calendar.getTimeInMillis());
        values.put("reportDate", simpleDateFormat.format(calendar.getTime()));
        values.put("reportTime", simpleTimeFormat.format(calendar.getTime()));
        values.put("latitude", location.getLatitude());
        values.put("longitude", location.getLongitude());
        if (location.hasAccuracy()) values.put("accuracy", location.getAccuracy());
        if (location.hasAltitude()) values.put("altitude", location.getAltitude());
        if (location.hasBearing()) values.put("bearing", location.getBearing());
        if (location.hasSpeed()) values.put("speed", location.getSpeed());

        return values;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        this.context = context;
        if (intent.getAction() != null && intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
            init(context, intent);
        else initLr(context);
    }
}
